﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DeepZoomPivotConstructor.PivotLib;
using DeepZoomPivotConstructor.VisualLib;
using System.IO;
using DeepZoomPivotConstructor.PivotLib.PivotSchema;
using System.Xml.Serialization;

namespace t_PivotLib
{
    [TestClass]
    public class t_PivotProcessor
    {
        [TestMethod]
        public void TestCtor()
        {
            var p = new PivotProcessor(new t_TestingLibrary.TestLogger());
        }

        [TestMethod]
        public void TestSingleImageCollection()
        {
            PivotCollection c = new PivotCollection();
            PivotImage img = new PivotImage(new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100));
            img.Name = "Name1";
            img.Description = "Descrip";
            c.Add(img);

            DirectoryInfo inf = new DirectoryInfo(".\\TestSingleImageCollectoin");
            if (inf.Exists)
            {
                inf.Delete(true);
            }

            PivotProcessor p = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var collecitonFile = p.CreatePivotCollection(c, inf, "TestSingleImageCollectoin");
            Assert.IsTrue(collecitonFile.Exists, "The collection file doesn't exist!");
            Assert.AreEqual(".cxml", collecitonFile.Extension, "Wrong extension for the main guy coming back!");

            var col = LoadCollectoin(collecitonFile);
            Assert.AreEqual(1, col.Items.Length, "Expected only one 'main' item");
            Assert.AreEqual(1, col.Items[0].Item.Length, "Expected only one image!");
            Assert.AreEqual("Name1", col.Items[0].Item[0].Name, "Expected the name to be correctly set!");
            Assert.AreEqual("Descrip", col.Items[0].Item[0].Description, "Descirption for the img didn't make it through");
        }

        [TestMethod]
        public void TestEmptyCollection()
        {
            PivotCollection pc = new PivotCollection();
            DirectoryInfo dir = new DirectoryInfo(".\\TestEmptyCollection");
            PivotProcessor proc = new PivotProcessor(new t_TestingLibrary.TestLogger());
            proc.CreatePivotCollection(pc, dir, "test");
        }

        /// <summary>
        /// Gets back the XML from the file.
        /// </summary>
        /// <param name="collecitonFile"></param>
        /// <returns></returns>
        private Collection LoadCollectoin(FileInfo collecitonFile)
        {
            using (var reader = collecitonFile.OpenText())
            {
                var deser = new XmlSerializer(typeof(Collection));
                return deser.Deserialize(reader) as Collection;
            }
        }

        [TestMethod]
        public void TestMultipleImageCollection()
        {
            PivotCollection c = new PivotCollection();
            AddImages(c, 10);

            DirectoryInfo inf = new DirectoryInfo(".\\TestMultipleImageCollection");
            if (inf.Exists)
            {
                inf.Delete(true);
            }

            PivotProcessor p = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var collecitonFile = p.CreatePivotCollection(c, inf, "TestSingleImageCollectoin");
            Assert.IsTrue(collecitonFile.Exists, "The collection file doesn't exist!");
            Assert.AreEqual(".cxml", collecitonFile.Extension, "Wrong extension for the main guy coming back!");
        }

        /// <summary>
        /// Add some number of images to the thing
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="numberOfImages"></param>
        private void AddImages(PivotCollection collection, int numberOfImages)
        {
            for (int i = 0; i < numberOfImages; i++)
            {
                PivotImage img = new PivotImage(new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100));
                collection.Add(img);
            }
        }

        [TestMethod]
        public void TestFacetString()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var fac = GetFacet (pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetString"), "Name"), 0, 0);
            Assert.AreEqual("name", fac.Name, "Facet name didn't come back right");
            Assert.AreEqual("dude", fac.String[0].Value, "Got incorrect type for the value");
        }

        [TestMethod]
        public void TestFacetNumber()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", (decimal) 44.4 } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var fac = GetFacet(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetString"), "Name"),0, 0);
            Assert.AreEqual("name", fac.Name, "Facet name didn't come back right");
            Assert.AreEqual((decimal) 44.4, fac.Number[0].Value, "Got incorrect type for the value");
        }

        [TestMethod]
        public void TestFacetDateTime()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            var now = DateTime.Now;
            PivotImage target = new PivotImage(v) { { "name", now} };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var fac = GetFacet(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetString"), "Name"), 0, 0);
            Assert.AreEqual("name", fac.Name, "Facet name didn't come back right");
            Assert.AreEqual(now, fac.DateTime[0].Value, "Got incorrect type for the date");
        }

        [TestMethod]
        public void TestFacetLink()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude", new Uri("http://www.cnn.com") } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var fac = GetFacet(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetString"), "Name"), 0, 0);
            Assert.AreEqual("name", fac.Name, "Facet name didn't come back right");
            Assert.AreEqual("dude", fac.Link[0].Name, "Got incorrect type for the href name");
            Assert.AreEqual("http://www.cnn.com", fac.Link[0].Href, "Got incorrect type for the href");
        }

        [ExpectedException(typeof(InvalidOperationException))]
        public void TestDifferentFacetTypes()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" }, {"name", "fork", new Uri("http://www.cnn.com")} };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetString"), "Name");
        }

        [TestMethod]
        public void TestFacetCatalog()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" }, { "name", "fork" } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalog"), "Name"));
            Assert.AreEqual(1, col.FacetCategories.FacetCategory.Length, "The # of facet categories isn't right");
            Assert.AreEqual("name", col.FacetCategories.FacetCategory[0].Name, "The name of the first facet catagory is not right");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsWordWheelVisibleSpecified, "wheel visible specified");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsWordWheelVisible, "wheel visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsMetaDataVisibleSpecified, "metadata visible specified");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsMetaDataVisible, "metadata visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsFilterVisibleSpecified, "filter visible specified");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsFilterVisible, "filter visible");
        }

        [TestMethod]
        public void TestFacetCatalogTypeString()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" }};
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogTypeString"), "Name"));
            Assert.AreEqual(facetType.String, col.FacetCategories.FacetCategory[0].Type, "String type isn't right");
        }

        [TestMethod]
        public void TestFacetCatalogTypeNumber()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", (decimal) 5.3 } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogTypeNumber"), "Name"));
            Assert.AreEqual(facetType.Number, col.FacetCategories.FacetCategory[0].Type, "number type isn't right");
        }

        [TestMethod]
        public void TestFacetCatalogTypeDateTime()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", DateTime.Now } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogTypeDateTime"), "Name"));
            Assert.AreEqual(facetType.DateTime, col.FacetCategories.FacetCategory[0].Type, "DateTime type isn't right");
        }

        [TestMethod]
        public void TestFacetCatalogTypeDateLink()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "Fork", new Uri("http://www.cnn.com") } };
            PivotCollection c = new PivotCollection() { target };
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogTypeDateLink"), "Name"));
            Assert.AreEqual(facetType.Link, col.FacetCategories.FacetCategory[0].Type, "DateTime type isn't right");
        }

        [TestMethod]
        public void TestFacetCatalogSetWorldWheel()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" }};
            PivotCollection c = new PivotCollection() { target };
            c.FacetCatagories["name"].IsWordWheelVisible = false;
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogSetWorldWheel"), "Name"));

            Assert.AreEqual(false, col.FacetCategories.FacetCategory[0].IsWordWheelVisible, "wheel visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsMetaDataVisible, "metadata visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsFilterVisible, "filter visible");
        }

        [TestMethod]
        public void TestFacetCatalogSetMetadata()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" } };
            PivotCollection c = new PivotCollection() { target };
            c.FacetCatagories["name"].IsMetaDataVisible = false;
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogSetMetadata"), "Name"));

            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsWordWheelVisible, "wheel visible");
            Assert.AreEqual(false, col.FacetCategories.FacetCategory[0].IsMetaDataVisible, "metadata visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsFilterVisible, "filter visible");
        }

        [TestMethod]
        public void TestFacetCatalogSetFilter()
        {
            Visual v = new VisualSingleImage(new FileInfo("..\\..\\..\\t_PivotLib\\pic1.png"), 100);
            PivotImage target = new PivotImage(v) { { "name", "dude" } };
            PivotCollection c = new PivotCollection() { target };
            c.FacetCatagories["name"].IsFilterVisible = false;
            var pp = new PivotProcessor(new t_TestingLibrary.TestLogger());
            var col = LoadCollectoin(pp.CreatePivotCollection(c, new DirectoryInfo("\\TestFacetCatalogSetFilter"), "Name"));

            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsWordWheelVisible, "wheel visible");
            Assert.AreEqual(true, col.FacetCategories.FacetCategory[0].IsMetaDataVisible, "metadata visible");
            Assert.AreEqual(false, col.FacetCategories.FacetCategory[0].IsFilterVisible, "filter visible");
        }
        /// <summary>
        /// Gets the requested facet. Assumes everything exists!
        /// </summary>
        /// <param name="fileInfo"></param>
        /// <param name="imageIndex"></param>
        /// <param name="facetIndex"></param>
        /// <returns></returns>
        private DeepZoomPivotConstructor.PivotLib.PivotSchema.facet GetFacet(FileInfo fileInfo, int imageIndex, int facetIndex)
        {
            Collection c = LoadCollectoin(fileInfo);
            return c.Items[0].Item[imageIndex].Facets.Facet[facetIndex];
        }
        
    }
}
